package reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author wei.zhao
 * @description:
 * @date 2021年12月31日 11:09
 */
public class Test {

    private static final String CLASS_NAME = "reflection.Person";

    public static void main(String[] args) throws Exception {
        testGetClass();
        reflectNewInstance();
        reflectPrivateConstructor();
        reflectPrivateField();
        reflectPrivateMethod();
    }

    // 获取Class的三种方式
    public static void testGetClass() throws ClassNotFoundException {
        Class<Person> personClass = Person.class;
        System.out.println("类名.class：" + personClass);
        Class<? extends Person> personClass2 = new Person().getClass();
        System.out.println("对象.getClass()：" + personClass2);
        Class<?> personClass3 = Class.forName(CLASS_NAME);
        System.out.println("Class.forName()：" + personClass3);
    }

    // 创建对象
    public static void reflectNewInstance() throws Exception {
        Class<?> classPerson = Class.forName(CLASS_NAME);
        Object object = classPerson.newInstance();
        Person person = (Person) object;
        person.setName("张三");
        person.setAge(20);
        System.out.println("反射创建对象：" + person);
    }

    // 反射私有的构造方法
    public static void reflectPrivateConstructor() throws Exception {
        Class<?> classPerson = Class.forName(CLASS_NAME);
        Constructor<?> declaredConstructorPerson = classPerson.getDeclaredConstructor(String.class, int.class);
        declaredConstructorPerson.setAccessible(true);
        Object objectPerson = declaredConstructorPerson.newInstance("李四", 21);
        Person person = (Person) objectPerson;
        System.out.println("反射私有的构造方法：" + person);
    }

    // 反射私有属性
    public static void reflectPrivateField() throws Exception {
        Class<?> classPerson = Class.forName(CLASS_NAME);
        Person person = (Person) classPerson.newInstance();
        person.setName("王五");
        Field field = classPerson.getDeclaredField("name");
        field.setAccessible(true);
        String fieldValue = (String) field.get(person);
        System.out.println("反射私有属性：" + fieldValue);
    }

    // 反射私有方法
    public static void reflectPrivateMethod() throws Exception {
        Class<?> classPerson = Class.forName(CLASS_NAME);
        Method methodPerson = classPerson.getDeclaredMethod("sayHello", String.class);
        methodPerson.setAccessible(true);
        Object objectPerson = classPerson.newInstance();
        System.out.print("反射私有方法：");
        methodPerson.invoke(objectPerson, "马六");
    }

}

